package com.mall.alipay.template;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.mall.alipay.feign.BookingFeign;
import com.mall.alipay.feign.OrderFeign;
import com.mall.alipay.feign.SeckillItemFeign;
import com.mall.constant.enums.BookingRootStatus;
import com.mall.constant.enums.OrderStatus;
import com.mall.constant.enums.OrderType;
import com.mall.constant.strings.AliyunServiceMsg;
import com.mall.constant.strings.ConstantStrings;
import com.mall.constant.strings.MapMsg;
import com.mall.entity.TbSeckillItem;
import com.mall.entity.bargain.BgOrder;
import com.mall.entity.groupbooking.GbRoot;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author White
 * @version 1.0
 * @email 616769721@qq.com
 * @date 2021/7/22 16:24
 */
@Component
public class AlipayTemplate {

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private SeckillItemFeign seckillItemFeign;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Autowired
    private BookingFeign bookingFeign;


    @Autowired
    private Redisson redisson;

    /**
     *
     * @param orderId 订单id
     * @return String
     * @throws AlipayApiException api接口异常
     */
    public String doPay(Long orderId) throws AlipayApiException {
        BgOrder bgOrder = orderFeign.findOne(orderId);
        String outTradeNo=bgOrder.getId().toString();
        String totalAmount=bgOrder.getPrice().toString();
        String subject=bgOrder.getItemSpecId().toString();
        String body ="";
        //1、根据支付宝的配置生成一个支付客户端
        AlipayClient alipayClient = new DefaultAlipayClient(AliyunServiceMsg.GATEWAY_URL,
                AliyunServiceMsg.APP_ID, AliyunServiceMsg.MERCHANT_PRIVATE_KEY, "json",
                AliyunServiceMsg.CHARSET, AliyunServiceMsg.ALIPAY_PUBLIC_KEY, AliyunServiceMsg.SIGN_TYPE);
        //2、创建一个支付请求 //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AliyunServiceMsg.RETURN_URL);
        alipayRequest.setNotifyUrl(AliyunServiceMsg.NOTIFY_URL);
        alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
                + "\"total_amount\":\""+ totalAmount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        return alipayClient.pageExecute(alipayRequest).getBody();
    }

    /**
     * 支付成功修改订单状态
     * @param outTradeNo 订单号
     */
    public void paySuccess(String outTradeNo) {
        //feign调用更新订单状态
        orderFeign.updateOrderStatus(Long.parseLong(outTradeNo), OrderStatus.HAVE_PAID.getCode());
        //根据订单id查询相应的订单
        BgOrder bgOrderById = orderFeign.findOne(Long.parseLong(outTradeNo));
        //获取订单类型
        String type = bgOrderById.getType();
        RMap<Integer, GbRoot> rootMap = redisson.getMap(MapMsg.BOOKING_ROOT_REDIS_MAP);
        //判断订单为哪种类型
        if (OrderType.GENERAL.getCode().equals(type)){
            System.out.println("普通商品订单："+outTradeNo+"，已支付");
        }
        else if (OrderType.SECKILL.getCode().equals(type)){
            //删除过期回滚标志
            redisTemplate.delete(ConstantStrings.IF_SECKILL_ORDER_ID+outTradeNo);
            System.out.println("秒杀商品订单："+outTradeNo+"，已支付");
            //feign调用通过id获取对应的秒杀商品
            TbSeckillItem byId = seckillItemFeign.findById(bgOrderById.getOrderItemId());
            //修改数据库中的销量
            byId.setSaleNum(byId.getSaleNum()+1);
            //如果卖完则修改状态
            if (byId.getSeckillNum().equals(byId.getSaleNum())){
                byId.setStatus("3");
            }
            //将修改完的数据更新到数据库
            seckillItemFeign.update(byId);
        }
        else if (OrderType.BARGAIN.getCode().equals(type)){
            System.out.println("砍价商品订单："+outTradeNo+"，已支付");
        }
        else if (OrderType.BOOKING_ROOT.getCode().equals(type)){
            //删除过期回滚标志
            redisTemplate.delete(ConstantStrings.IF_BOOKING_ROOT_ORDER_ID+outTradeNo);
            System.out.println("拼团商品团长订单："+outTradeNo+"，已支付");
            //获取团id
            Long rootId = bgOrderById.getOrderItemId();
            RLock lock = redisson.getLock(rootId.toString());
            GbRoot gbRoot=null;
            try {
                lock.lock(5, TimeUnit.SECONDS);
                //获取redis中的团
                gbRoot = rootMap.get(Integer.parseInt(rootId.toString()));
                //更新团状态
                gbRoot.setStatus(BookingRootStatus.unfinished.getCode());
                //更新到redis中
                rootMap.put(gbRoot.getId(),gbRoot);
            }finally {
                lock.unlock();
            }
            //修改数据库中团的状态
            bookingFeign.updateStatusById(gbRoot.getId(),BookingRootStatus.unfinished.getCode());
        }
        else if (OrderType.BOOKING_RECORD.getCode().equals(type)){
            //删除过期回滚标志
            redisTemplate.delete(ConstantStrings.IF_BOOKING_RECORD_ORDER_ID+outTradeNo);
            System.out.println("拼团商品普通订单："+outTradeNo+"，已支付");
            //获取拼团记录id
            Long recordId = bgOrderById.getOrderItemId();
            //将该记录添加到数据库中
            bookingFeign.recordToMysql(recordId);
        }
    }
}
